package pl.edu.pw.perg.compinfodb.ui;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

import pl.edu.pw.perg.compinfodb.entities.VirtualElement;

public class PathTreeUtils {

  /**
   * Metoda sklejajaca dwa drzewa poprzez ich korzenie oraz element
   * zewnetrzny po srodku. 
   * Zwraca listy sklejonych galezi, przy czym kazda prawa jest dodawana
   * w porzadku odwrotnym.
   * 
   * @param leftTreeRoot
   * @param virtualElement2
   * @param rightTreeRoot
   * @return
   */
    static List<List<VirtualElement>> createPathList(DefaultMutableTreeNode leftTreeRoot,
        VirtualElement virtualElement2, DefaultMutableTreeNode rightTreeRoot) {
      List<List<VirtualElement>> finalList = new ArrayList<List<VirtualElement>>();
      List<List<VirtualElement>> leftList = createListsFromTree(leftTreeRoot);
      List<List<VirtualElement>> rightList = createListsFromTree(rightTreeRoot);
//      dla kazdej listy lewej
      for (List<VirtualElement> list : leftList) {
//        dodajemy srodek
        List<VirtualElement> path = new ArrayList<VirtualElement>();
        path.addAll(list);
        path.add(virtualElement2);
//        oraz doklejamy w odwroconej kolejnosci kazda liste z prawej
        for (List<VirtualElement> list2 : rightList) {
          List<VirtualElement> path2 = new ArrayList<VirtualElement>();
          path2.addAll(path);
          for (int i = list2.size() - 1; i >= 0; i--) {
            path2.add(list2.get(i));
          }
          finalList.add(path2);
        }
      }
      return finalList;
    }

  /**
   * Metoda tworzaca liste galezi drzewa (kazda galaz to lista elementow)
   * @param treeRoot
   * @return
   */
    static List<List<VirtualElement>> createListsFromTree(
        DefaultMutableTreeNode treeRoot) {
//      jesli nie jest lisciem
      if(!treeRoot.isLeaf()){
        List<List<VirtualElement>> lists = new ArrayList<List<VirtualElement>>();
        Enumeration<DefaultMutableTreeNode> children = treeRoot.children();
        while (children.hasMoreElements()) {
          DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) 
            children.nextElement();
//          wyciagamy listy z kazdego dziecka
          List<List<VirtualElement>> list = createListsFromTree(childNode);
//          i do kazdej dodajemy biezacy element
          for (List<VirtualElement> tmpList : list) {
            tmpList.add((VirtualElement) treeRoot.getUserObject());
            lists.add(tmpList);
          }        
        }
        return lists;
      }    
//      jesli jest lisciem zwracamy liste list, z jedna lista go zawierajaca
      List<List<VirtualElement>> lists = new ArrayList<List<VirtualElement>>();
      List<VirtualElement> listStart = new ArrayList<VirtualElement>();
      listStart.add((VirtualElement) treeRoot.getUserObject());
      lists.add(listStart);
      return lists;
    }

}
